﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using ApiScanner.Core;
using InfiniTec;

namespace ApiScanner
{
    static class Program
    {
        static int Main(string[] args)
        {
            if (args.Length != 1)
            {
                ShowUsage(null);
                return 1;
            }
            var configFile = args[0];
            var configuration = ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap {ExeConfigFilename = configFile}, ConfigurationUserLevel.None);

            var testRunnerConfig = ScannerConfigurationSection.Open(configuration);
            if (testRunnerConfig == null)
            {
                ShowUsage("The configuration is empty.");
            }

            var runner = new TestRunner(testRunnerConfig);

            var artifacts = runner.Run(Console.WriteLine).ToArray();
            var errors = artifacts.OfType<ScannerError>().ToArray();
            var events = artifacts.Except(errors).ToArray();

            Console.Out.WriteLine("Finished");

            Console.Out.WriteLine("API dependencies found: {0}", events.Length);
            Console.Out.WriteLine("Error occured: {0}", errors.Length);

            Console.Out.WriteLine("Errors:");

            foreach (var error in errors)
            {
                Console.Out.WriteLine(error.Location);
                Console.Out.WriteLine(error.Exception.Message);
                Console.Out.WriteLine();
            }

            Console.Out.WriteLine();
            Console.Out.WriteLine("API Dependendies found:");
            foreach (var artifact in events)
            {
                PrintArtifact(artifact);
                Console.Out.WriteLine();
            }

            return 0;
        }

        private static void PrintArtifact(Artifact artifact)
        {
            var fileScannerArtifact = artifact as FileSystemArtifact;
            var smtpEventBinding = artifact as SmtpServerEventBinding;
            var storeEventBinding = artifact as StoreEventBinding;

            if (fileScannerArtifact != null)
            {
                Console.Out.WriteLine("File {0}", fileScannerArtifact.FileName);
                Console.Out.WriteLine("Dependencies detected: {0}", fileScannerArtifact.DllsFound.Join(", "));
            }
            else if (smtpEventBinding != null)
            {
                Console.Out.WriteLine("Smtp Server event binding");
                Console.Out.WriteLine("Display name: {0}", smtpEventBinding.Name);
                Console.Out.WriteLine("Sink Class: {0}", smtpEventBinding.SinkClass);
            }
            else if (storeEventBinding != null)
            {
                Console.Out.WriteLine("Exchange Store Event binding");
                Console.Out.WriteLine("Display name: {0}", storeEventBinding.Name);
                Console.Out.WriteLine("Url: {0}", storeEventBinding.Url);
                Console.Out.WriteLine("Sink class: {0}", storeEventBinding.SinkClass);
                Console.Out.WriteLine("Script url: {0}", storeEventBinding.ScriptUrl);
                Console.Out.WriteLine("Match scope: {0}", storeEventBinding.MatchScope);
            }
        }

        private static void ShowUsage(string errorMessage)
        {
            if (errorMessage.IsNotNullOrEmpty())
            {
                Console.Out.WriteLine(errorMessage);
                Console.Out.WriteLine();
            }

            Console.Out.WriteLine("Usage: ApiScanner {configuration file}");
        }
    }
}
